/*
 * CAD System for seamlessly constructing 2D and 3D scenes with aspects and motion
 * Copyright (C) 2013 Bernhard Haumacher and others
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.haumacher.draw5d.math.d2.constructions.internal;

import static de.haumacher.draw5d.math.d2.D2Computations.*;
import static de.haumacher.draw5d.math.d2.constructions.Factory.*;
import de.haumacher.draw5d.dataflow.Property;
import de.haumacher.draw5d.dataflow.Scope;
import de.haumacher.draw5d.dataflow.core.InputImpl;
import de.haumacher.draw5d.math.d2.D2;
import de.haumacher.draw5d.math.d2.D2Base;
import de.haumacher.draw5d.math.d2.D2Computation;
import de.haumacher.draw5d.math.d2.Straight;

/**
 * {@link D2Computation} that computes the point on the given {@link #STRAIGHT} with the shortest
 * distance to the given {@link #POINT}.
 * 
 * @author <a href="mailto:haui@haumacher.de">Bernhard Haumacher</a>
 * @version $Revision: 30 $ $Author: haumacher@googlemail.com $ $Date: 2013-07-27 20:49:19 +0200
 *          (Sat, 27 Jul 2013) $
 */
public class ProjectionOnStraightImpl extends D2ComputationImpl {

	public static final Property<Straight> STRAIGHT = property(Straight.class);

	public static final Property<D2> POINT = property(D2.class);

	private D2Base _originPoint = d2Base();

	private D2Base _offset = d2Base();

	/**
	 * Creates a {@link ProjectionOnStraightImpl}.
	 * 
	 * @param scope
	 *        See {@link #getScope()}.
	 */
	public ProjectionOnStraightImpl(Scope scope) {
		super(scope, STRAIGHT, POINT);
	}

	@Override
	public void validate() {
		Straight straight = get(STRAIGHT);
		D2Base origin = straight.getOrigin();
		D2Base unit = straight.getUnit();

		sub(_originPoint, get(POINT), origin);
		double factor = scalarProduct(unit, _originPoint);

		D2 result = getResult();
		multiply(_offset, unit, factor);
		add(result, origin, _offset);
	}

}
